package cn.congine.wizarpos.mall.weChat.bussiness;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.congine.wizarpos.mall.entity.MyOnlineActivity;
import cn.congine.wizarpos.mall.entity.MyOnlineActivityDetail;
import cn.congine.wizarpos.mall.entity.MyRedEnvelopes;
import cn.congine.wizarpos.mall.entity.MyShake;
import cn.congine.wizarpos.mall.entity.SysInToken;
import cn.congine.wizarpos.mall.model.dzx.DzxBindSendTicketInput;
import cn.congine.wizarpos.mall.model.dzx.DzxBindSendTicketOutput;
import cn.congine.wizarpos.mall.model.open.CommonResultOutput;
import cn.congine.wizarpos.mall.model.open.DzxWxHongbaoSendInput;
import cn.congine.wizarpos.mall.model.open.MemberReadRecordInput;
import cn.congine.wizarpos.mall.model.open.MemberReadRecordOutput;
import cn.congine.wizarpos.mall.model.open.MrtWechartUserInfoUpdateInput;
import cn.congine.wizarpos.mall.model.open.MrtWechartUserInfoUpdateOutput;
import cn.congine.wizarpos.mall.model.open.TicketDefUpdateInput;
import cn.congine.wizarpos.mall.model.open.TicketDefUpdateOutput;
import cn.congine.wizarpos.mall.model.open.WeChartMemberBankCardBindInput;
import cn.congine.wizarpos.mall.model.open.WeChartMemberBankCardBindOutput;
import cn.congine.wizarpos.mall.model.open.WxCardBindInput;
import cn.congine.wizarpos.mall.model.open.WxCardBindOutput;
import cn.congine.wizarpos.mall.service.MyOnlineActivityDetailService;
import cn.congine.wizarpos.mall.service.MyRedEnvelopesService;
import cn.congine.wizarpos.mall.service.MyShakeService;
import cn.congine.wizarpos.mall.service.SysInTokenService;
import cn.congine.wizarpos.mall.service.impl.WPosHttpClient;
import cn.congine.wizarpos.mall.service.impl.WizarposOpenRestClient;
import cn.congine.wizarpos.mall.utils.CommonUtil;
import cn.congine.wizarpos.mall.utils.SysConstants;
import cn.congine.wizarpos.mall.weChat.response.Article;
import cn.congine.wizarpos.mall.weChat.response.NewsMessage;
import cn.congine.wizarpos.mall.weChat.response.TextMessage;
import cn.congine.wizarpos.mall.weChat.util.MessageUtil;

import com.alibaba.fastjson.JSONObject;

/**
 * 处理微信推送消息
 * 
 * @author GuZhenJuan
 *
 */
@Component
public class WechartCoreService {
	private static Logger log = LoggerFactory.getLogger(WechartCoreService.class);
	
	@Autowired
	private WPosHttpClient wposHttpClient;
	@Autowired
	private WizarposOpenRestClient wizarposOpenRestClient;	
	@Autowired
	private SysInTokenService sysInTokenService;
	@Autowired
	private MyRedEnvelopesService myRedEnvelopesService;
	@Autowired
	private MyShakeService myShakeService;
	@Autowired
	private MyOnlineActivityDetailService myOnlineActivityDetailService;

	private JSONObject mrtTicketDefService;
	/**
	 * 处理微信发来的请求
	 * 
	 * @param request
	 * @return
	 */
	public String processRequest(HttpServletRequest request,
			HttpServletResponse response) {
		String respMessage = null;
		try {
			Map<String, String> requestMap = MessageUtil.parseXml(request);
			String fromUserName = requestMap.get("FromUserName");
			String toUserName = requestMap.get("ToUserName");
			String msgType = requestMap.get("MsgType");
		
			String respContent = "";
			if (MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgType)) {

				String eventType = requestMap.get("Event");
				ActionResponse actionResponse = null;
				if (MessageUtil.EVENT_TYPE_UNSUBSCRIBE.equals(eventType)) {
					// 用户取消关注
					actionResponse = unSubscribe(fromUserName, toUserName);
					
				} else if (MessageUtil.EVENT_TYPE_SUBSCRIBE.equals(eventType)
						|| MessageUtil.EVENT_TYPE_SCAN.equals(eventType)) {
					respContent = "谢谢您的关注，我们会努力做到更好。";
					// 用户订阅事件
					actionResponse = subscribe(fromUserName, toUserName);
					
					String eventKey = requestMap.get("EventKey");
					System.out.println("eventKey = " + eventKey);
					if (StringUtils.isEmpty(eventKey)) {
						// 图文消息
						List<Article> articles = new ArrayList<Article>();
						Article article = new Article();
						article.setTitle("谢谢您关注");
						article.setDescription("您的关注是我们生存的动力");
						article.setPicUrl("http://image.wizarpos.com/1003000100000092015043017295357654.png");
						article.setUrl("http://mp.weixin.qq.com/s?__biz=MzA3OTE2OTY2OQ==&mid=215702317&idx=1&sn=7edb7065d64301980914e1d883e5bc3b#rd");
						articles.add(article);
						
						NewsMessage newsMessage = new NewsMessage();
						newsMessage.setToUserName(fromUserName);
						newsMessage.setFromUserName(toUserName);
						newsMessage.setCreateTime(new Date().getTime());
						newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
						newsMessage.setFuncFlag(0);
						newsMessage.setArticleCount(1);
						newsMessage.setArticles(articles);
						respMessage = MessageUtil.newsMessageToXml(newsMessage);
						
						return respMessage;
					}
					
					if (eventKey != null && ("qrscene_0".equals(eventKey) || "0".equals(eventKey))) {
						// 订阅并有二维码的参数值 0,用户银行卡绑定事件
						String ticketId = requestMap.get("Ticket");
						ticketId = URLEncoder.encode(ticketId, "utf-8");
						actionResponse = bankCardBind(fromUserName, ticketId);				
						
					} else if (eventKey != null	&& ("qrscene_1".equals(eventKey) || "1".equals(eventKey))) { 
						// 订阅并有二维码的参数值1,用户会员卡绑定事件
						String ticketId = requestMap.get("Ticket");
						ticketId = URLEncoder.encode(ticketId, "utf-8");
						actionResponse = cardBind(fromUserName, ticketId);
					} else if (eventKey != null	&& ("qrscene_2".equals(eventKey) || "2".equals(eventKey))) {
						// 订阅并有二维码的参数值2,东志信联盟商户二维码摇一摇关注送券事件
						String ticketId = requestMap.get("Ticket");
						ticketId = URLEncoder.encode(ticketId, "utf-8");
						actionResponse = dzxBindSendTicket(fromUserName, ticketId);
					}else if (eventKey != null	&& ("qrscene_3".equals(eventKey) || "3".equals(eventKey))) { 
						// 订阅并有二维码的参数值1,用户会员卡绑定事件
						String ticketId = requestMap.get("Ticket");
						ticketId = URLEncoder.encode(ticketId, "utf-8");
						sendHongbao(fromUserName, ticketId);
					}
				} else if (MessageUtil.EVENT_TYPE_CLICK.equals(eventType)) {
					// 自定义菜单点击事件
//					String eventKey = requestMap.get("EventKey");
				} else if (MessageUtil.EVENT_TYPE_VIEW.equals(eventType)){
//					String eventKey = requestMap.get("EventKey"); // TODO 时候校验跳转地址
				    // 记录用户访问
					memberReadRecord(fromUserName, toUserName);
				} else if (MessageUtil.CARD_PASS_CHECK.equals(eventType)) {
					// 微信卡券审核通过
					String cardid = requestMap.get("CardId");
					ticketPass(cardid, toUserName);
				} else if (MessageUtil.CARD_NOT_PASS_CHECK.equals(eventType)) {
					// 卡券审核未通过处理
					String cardid = requestMap.get("CardId");
					ticketUnpass(cardid, toUserName);
				} else if (MessageUtil.USER_GET_CARD.equals(eventType)) {
					// 用户领券会员卡类型卡券事件
					String code = requestMap.get("UserCardCode");
					String wxCardId = requestMap.get("CardId");
					actionResponse = userGetCard(fromUserName, wxCardId, code, toUserName);
				} else if (MessageUtil.USER_CONSUME_CARD.equals(eventType)) {
					respContent = "您已成功使用了一张本商户优惠券，谢谢您的光顾，欢迎再次光临。";
				}
				if (actionResponse != null) {
					try {
						respContent = processResponse(response, actionResponse);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				
			} else if (MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(msgType)) {
				respContent = "谢谢您发送消息";
			} else if (MessageUtil.REQ_MESSAGE_TYPE_IMAGE.equals(msgType)) {
				respContent = "谢谢您发送图片！";
			} else if (MessageUtil.REQ_MESSAGE_TYPE_LOCATION.equals(msgType)) {
				respContent = "谢谢您发送地理位置！";
			} else if (MessageUtil.REQ_MESSAGE_TYPE_LINK.equals(msgType)) {
				respContent = "谢谢您发送链接！";
			} else if (MessageUtil.REQ_MESSAGE_TYPE_VOICE.equals(msgType)) {
				respContent = "谢谢您发送音频！";
			}
			
			TextMessage textMessage = new TextMessage();
			textMessage.setToUserName(fromUserName);
			textMessage.setFromUserName(toUserName);
			textMessage.setCreateTime(new Date().getTime());
			textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
			textMessage.setFuncFlag(0);
			textMessage.setContent(respContent);
			respMessage = MessageUtil.textMessageToXml(textMessage);
			
		} catch (Exception e) {
			e.printStackTrace();
		}

		return respMessage;
	}

	/**
	 * 取消关注处理
	 * @param parameter
	 * @return
	 */
	private ActionResponse unSubscribe(String openId, String pid) {
		MrtWechartUserInfoUpdateInput input = new MrtWechartUserInfoUpdateInput();
		input.setPid(pid);
		input.setOpenId(openId);
		input.setSubscribe("0");
		MrtWechartUserInfoUpdateOutput output = (MrtWechartUserInfoUpdateOutput) wizarposOpenRestClient.post(input, "/wxshop/userinfoupdate", MrtWechartUserInfoUpdateOutput.class);				
		JSONObject message = new JSONObject();		
		if (output == null) {
			message.put("message", SysConstants.SYSTEM_RRROR);
			return new ActionResponse(1, "error", message);					
		} else if ("0".equals(output.getCode())) {
			message.put("message", "关注已取消");
			return new ActionResponse(0, "success", message);			
		} else if ("60059".equals(output.getCode())) {
			message.put("message", SysConstants.NO_MERCHANT);
			return new ActionResponse(1, "error", message);
		} else {
			message.put("message", SysConstants.SYSTEM_RRROR);
			return new ActionResponse(1, "error", message);			
		}
		
	}
	
	/**
	 * 用户关注处理
	 * @param parameter
	 * @return
	 */
	private ActionResponse subscribe(String openId, String pid) {
		log.debug("--------------subscribe ------------");
		log.debug("openId is " + openId);
		log.debug("pid is " + pid);

		MrtWechartUserInfoUpdateInput input = new MrtWechartUserInfoUpdateInput();
		input.setPid(pid);
		input.setOpenId(openId);
		input.setSubscribe("1");
		MrtWechartUserInfoUpdateOutput output = (MrtWechartUserInfoUpdateOutput) wizarposOpenRestClient.post(input, "/wxshop/userinfoupdate", MrtWechartUserInfoUpdateOutput.class);				
		JSONObject message = new JSONObject();		
		if (output == null) {
			message.put("message", SysConstants.SYSTEM_RRROR);
			return new ActionResponse(1, "error", message);					
		} else if ("0".equals(output.getCode())) {
			message.put("message", "关注成功");
			return new ActionResponse(0, "success", message);			
		} else if ("60059".equals(output.getCode())) {
			message.put("message", SysConstants.NO_MERCHANT);
			return new ActionResponse(1, "error", message);
		} else {
			message.put("message", SysConstants.SYSTEM_RRROR);
			return new ActionResponse(1, "error", message);			
		}
	}
	

	/**
	 * 银行卡绑定
	 * @param parameter
	 * @return
	 */
	private ActionResponse bankCardBind(String openId, String ticketId) {
		// 返回消息
		JSONObject message = new JSONObject();
		WeChartMemberBankCardBindInput input = new WeChartMemberBankCardBindInput();
		input.setOpenId(openId);
		input.setTicketId(ticketId);
		input.setOperate("0");
		WeChartMemberBankCardBindOutput output = (WeChartMemberBankCardBindOutput) wizarposOpenRestClient.post(input, "/wechart/bankcard/update", WeChartMemberBankCardBindOutput.class);		
		if (output == null) {
			message.put("message", "系统错误，会员卡绑定失败！");
			return new ActionResponse(1, "success", message);			
		}
		message.put("message", output.getMessage());
		return new ActionResponse(0, "success", message);		
	}
	
	/**
	 * 微信会员卡绑定实体卡
	 * @param parameter
	 * @return
	 */
	private ActionResponse cardBind(String openId, String ticketId) {
		// 返回消息
		JSONObject message = new JSONObject();		
		WxCardBindInput input = new WxCardBindInput();
		input.setOpenId(openId);
		input.setTicketId(ticketId);
		WxCardBindOutput output = (WxCardBindOutput) wizarposOpenRestClient.post(input, "/wxshop/wxCardBind", WxCardBindOutput.class);
		
		if (output == null || "-1".equals(output.getCode())) {//系统错误，处理失败
			return new ActionResponse(1, "success", "系统错误，会员卡绑定失败！");				
		} else if ("0".equals(output.getCode())) {//操作成功
			message.put("message", "您已成功绑定实体会员卡与微信会员卡，更多优惠活动敬请期待！");
			return new ActionResponse(0, "success", message);			
		} else if ("60041".equals(output.getCode())) {//二维码已过期
			message.put("message", "本次小票的二维码已过期，下次刷卡消费后请及时扫描二维码。");
			return new ActionResponse(3, "error", message);			
		} else if ("60064".equals(output.getCode())) {//会员卡已绑定，无需再次绑定
			message.put("message", "你已经绑定了此会员卡，无需再次绑定");
			return new ActionResponse(1, "success", message);	
		} else if ("60065".equals(output.getCode())) {//会员卡已绑定其他微信会员，不能进行再次绑定
			message.put("message", "此会员卡已绑定其他微信会员，不能进行再次绑定！");
			return new ActionResponse(1, "success", message);		
		} else if ("60066".equals(output.getCode())) {//实体会员卡已绑定，不能进行再次绑定
			message.put("message", "您已经绑定过实体会员卡，不能进行再次绑定！");
			return new ActionResponse(1, "success", message);		
		} else {//60067，实体会员卡与微信会员卡绑定出错
			message.put("message", "实体会员卡与微信会员卡绑定出错，请联系商家！");
			return new ActionResponse(1, "fail", message);		
		}

	}
	
	/**
	 * 记录用户访问
	 * 
	 * @param requestMap
	 * @return
	 */
	private void memberReadRecord(String openId, String pid) {
		
		log.debug("--------------member read record------------");
		log.debug("openId is " + openId);
		log.debug("pid is " + pid);
		MemberReadRecordInput input = new MemberReadRecordInput();
		input.setOpenId(openId);
		input.setPid(pid);
		MemberReadRecordOutput output = (MemberReadRecordOutput) wizarposOpenRestClient.post(input, "/wechart/memberReadRecord", MemberReadRecordOutput.class);
		
		if (output == null) {//请求开放平台失败
			log.debug("请求开放平台失败。。。");
		} else if ("60019".equals(output.getCode())) {//60019非法微信号
			log.debug(output.getMessage());
		} else {// 0 操作成功
			if (output.getResult() != null) {//该pid下未找到商户
				log.debug(output.getResult());
			}
			log.debug(output.getMessage());
		}
		
	}
	
	// 处理结果
	private static String processResponse(HttpServletResponse response, ActionResponse actionResponse) throws IOException, ServiceException {
		response.setHeader("code", "" + actionResponse.getCode());
		if (null != actionResponse.getMessage()
				&& !"".equals(actionResponse.getMessage())) {
			response.setHeader("message",
					CommonUtil.base64Encoder(actionResponse.getMessage()));
		}
		
		String resJson = null;
		if (actionResponse.getData() != null) {
			resJson = actionResponse.getData().toString();
		}
		
		// 输出响应报文，json格式
		JSONObject message = JSONObject.parseObject(resJson);
		String resMsgs = message.getString("message");
		return resMsgs;
	}
	
	/**
	 * 微信卡券未审核通过
	 * 
	 * @param parameter
	 * @return
	 */
	private void ticketUnpass(String cardId, String gh) {
		TicketDefUpdateInput input = new TicketDefUpdateInput();
		input.setGhCode(gh);
		input.setWxCodeId(cardId);
		input.setUsedFlag("2");//是否启用 0:无效 1:有效，审核通过 2:审核未通过
		TicketDefUpdateOutput output = (TicketDefUpdateOutput) wizarposOpenRestClient.post(input, "/wxshop/ticketDefUpdate", TicketDefUpdateOutput.class);		
		if (output == null) {//请求开放平台失败
			log.debug("请求开放平台失败。。。");
		} else if ("0".equals(output.getCode())) {// 0 操作成功
			log.debug(output.getMessage());			
		} else {//60059非法的商户公众号openid,60038未知的微信卡券ID,60008非法入参
			log.debug(output.getMessage());
		}
	}
	
	/**
	 * 微信卡券审核通过
	 * 
	 * @param parameter
	 * @return
	 */
	private void ticketPass(String cardId, String gh) {
		
		TicketDefUpdateInput input = new TicketDefUpdateInput();
		input.setGhCode(gh);
		input.setWxCodeId(cardId);
		input.setUsedFlag("1");//是否启用 0:无效 1:有效，审核通过 2:审核未通过
		TicketDefUpdateOutput output = (TicketDefUpdateOutput) wizarposOpenRestClient.post(input, "/wxshop/ticketDefUpdate", TicketDefUpdateOutput.class);		
		if (output == null) {//请求开放平台失败
			log.debug("请求开放平台失败。。。");
		} else if ("0".equals(output.getCode())) {// 0 操作成功
			log.debug(output.getMessage());			
		} else {//60059非法的商户公众号openid,60038未知的微信卡券ID,60008非法入参
			log.debug(output.getMessage());
		}		
	}
	
	/**
	 * 用户领取卡券
	 * 
	 * @param parameter
	 * @return
	 */
	private ActionResponse userGetCard(String openId, String wxCardId, String code, String gh) {
		JSONObject message = new JSONObject();
		message.put("message", "恭喜您已成功领取了一张本商户的优惠券，请到微信卡包查看。");
		return new ActionResponse(0, "success", message);
	}
	
	/**
	 * 
	 * 
	 * @param fromUserName
	 * @param ticketId
	 */
	private void sendHongbao(String fromUserName, String ticketId) {
		SysInToken token = sysInTokenService.getSysInTokenByTokenId(ticketId);
		if (token == null) {// 红包记录不存在
			return; 
		}
		String id = token.getInfo(); // 红包定义id
		String activeId = token.getSubInfo();
		String mid = token.getMid();
		MyRedEnvelopes red = myRedEnvelopesService.getByMidAndMyShakeId(mid, id);
		if (red == null) { // 红包已经全部发完
			return;
		}
		Long amount = red.getAmount();
		MyOnlineActivity act = red.getMyOnlineActivity();
		String actName = act.getActivityName();
		String status = act.getStatus();
		if ("1".equals(status)) { // 1标示活动已经停止
			 return;
		}
		
		//请求开放平台发放红包
		DzxWxHongbaoSendInput input = new DzxWxHongbaoSendInput();
		input.setMid(mid);
		input.setOpenid(fromUserName);
		input.setActName(actName);
		input.setAmount(String.valueOf(amount));
		CommonResultOutput output = (CommonResultOutput) wizarposOpenRestClient.post(input, "/weixin/dzxSendWxHongbao", CommonResultOutput.class);				
		
		if (output != null && "0".equals(output.getCode())) {
			// 红包发送成功
			MyShake myShake = myShakeService.get(id);
			MyOnlineActivityDetail myOnlineActivityDetail = new MyOnlineActivityDetail();
			myOnlineActivityDetail.setOnlineActivityId(activeId);
			myOnlineActivityDetail.setPersonOpenId(fromUserName);
			myOnlineActivityDetail.setReceiveTime(new Date());
			myOnlineActivityDetail.setTicketMid(myShake.getTicketMid());
			myOnlineActivityDetail.setTicketType(myShake.getTicketType());
			myOnlineActivityDetail.setTicketContent(myShake.getTicketContent());
			myOnlineActivityDetailService.saveMyOnlineActivityDetail(myOnlineActivityDetail);	
			sysInTokenService.delete(token);
		}
	}
	
	/**
	 * 东志信联盟商户二维码摇一摇关注送券事件, 送券
	 * 
	 * @param fromUserName
	 * @param ticketId
	 * @return
	 */
	private ActionResponse dzxBindSendTicket(String fromUserName,
			String ticketId) {
		log.debug("--------------dzx openid binding and send ticket------------");
		DzxBindSendTicketInput   dzxBindSendTicketInput=new DzxBindSendTicketInput();

		
		dzxBindSendTicketInput.setOpenId(fromUserName);
		dzxBindSendTicketInput.setTicketId(ticketId);
		
		DzxBindSendTicketOutput output = (DzxBindSendTicketOutput) wizarposOpenRestClient.post(dzxBindSendTicketInput, "/dzx/bindSendTicket", DzxBindSendTicketOutput.class);
		
		JSONObject message = new JSONObject();
		
		if(output != null && "0".equals(output.getCode())){
			
			//message.put("message", "恭喜您已成功领取了一张本商户的优惠券，请到会员卡查看。");
			message.put("message", "恭喜您摇一摇获得优惠券，在右下方【会员卡】栏查看优惠券详情。");
			
		}
		
		return new ActionResponse(0, "success", message);
	}
}
